//
// Created by tang on 23-3-12.
//

#include "utils/dynamic_library.hpp"
#include "utils/log.hpp"

#if defined(_WIN32)

#define dll_open(name) ::LoadLibraryA(name)
#define dll_close(handle) ::FreeLibrary(handle)
#define dll_get_proc(handle, name) ::GetProcAddress(handle, name)

#elif defined(__unix__)

#include <dlfcn.h>

#define dll_open(name) dlopen(name, RTLD_NOW)
#define dll_close(handle) dlclose(handle)
#define dll_get_proc(handle, name) dlsym(handle, name)

#else
#error "Unsupported Platform!!"
#endif

DynamicLibrary::DynamicLibrary (const std::string &dll_path) {
    handle_ = dll_open (dll_path.c_str());
    if (!handle_) {
#if defined(_WIN32)
        L_ERROR("Load Library '%s' Failed: %d", dll_path.c_str(), GetLastError());
#else
        L_ERROR("Load Library '%s' Failed: %s", dll_path.c_str(), dlerror());
#endif
    }
}

DynamicLibrary::~DynamicLibrary () {
    if (handle_)
        dll_close (handle_);
    handle_ = invalid_dll;
}

void *DynamicLibrary::get_sym_addr (std::string_view sym_name, dll_handle_t handle)
{
    return dll_get_proc (handle, sym_name.data());
}
